---
title: Events
subtitle: Capture events from the router's request lifecycle
description: Capture standard and custom events from the Apollo GraphOS Router's request lifecycle services.
context:
  - telemetry
redirectFrom:
  - /graphos/routing/observability/telemetry/instrumentation/events
---

import RouterServices from '../../../../../shared/router-lifecycle-services.mdx';
import TelemetryPerformanceNote from '../../../../../shared/telemetry-performance.mdx';

An _event_ is used to signal when something of note happens in the [GraphOS Router's request lifecycle](/graphos/routing/request-lifecycle). Events are output to both logs and traces.

You can configure events for each service in `router.yaml`. Events can be standard or custom, and they can be triggered by configurable conditions.

## Event configuration

<PlanRequired plans={["Free", "Developer", "Standard", "Enterprise"]}/>

### Router request lifecycle services

<RouterServices />

The `router`, `supergraph`, `subgraph` and `connector` sections are used to define custom event configuration for each service:

```yaml title="future.router.yaml"
telemetry:
  instrumentation:
    events:
      router: # highlight-line
        # ...     
      supergraph: # highlight-line
        # ...
      subgraph: # highlight-line
        # ...
      connector: # highlight-line
        # ...
```

### Standard events

Each service has a set of standard events that can be configured:

* `request` - The request has been received.
* `response` - The response has been sent.
* `error` - An error in the request lifecycle has occurred.

<Note>

The `error` level applies only to request lifecycle errors, not GraphQL errors.

</Note>

To configure these events, set the level to `trace`, `info`, `warn`, `error` or `off` (default).

For example:

```yaml title="router.yaml"
telemetry:
  instrumentation:
    events:
      router:
        request: off
        response: off
        error: error
        # ...
```

But you can also enable these standard events based on [conditions](/router/configuration/telemetry/instrumentation/conditions) (not supported on batched requests).

For example:
```yaml title="router.yaml"
telemetry:
  instrumentation:
    events:
      router:
        request:
          level: info
          condition: # Only log the router request if you sent `x-log-request` with the value `enabled`
            eq:
            - request_header: x-log-request
            - "enabled"
        response: off
        error: error
      supergraph:
        response:
          level: info
          condition: # Only log the supergraph response containing graphql errors
            eq:
            - on_graphql_error: true
            - true
        error: error
        # ...
```


### Custom events

For each service you can also configure custom events.

```yaml title="future.router.yaml"
telemetry:
  instrumentation:
    events:
      router:
        # Custom events
        my.event: # This key will automatically be added as a 'type' attribute of the event
          # Custom event configuration
```

<Note>

<TelemetryPerformanceNote/>

</Note>

### `message`

Each custom event must have a message. This is a fixed value, and custom attributes should be used to add additional information.

```yaml title="future.router.yaml"
telemetry:
  instrumentation:
    events:
      router:
        acme.event:
          message: "my event message"
          # ...
```

### `on`

Each custom event must indicate when it should be triggered. This can be `request`, `response`, `event_response` or `error`.

```yaml title="future.router.yaml"
telemetry:
  instrumentation:
    events:
      router:
        acme.event:
          on: request # request, response, event_response, error
          # ...
```

> `event_response` is useful when you want to directly access to the json response body. It also works for subscription events and `@defer` chunks.

### `level`

Custom events have a level, `trace`, `debug`, `info`, `warn`, `error` or `off` (if you want to disable this event). The level determines the severity of the event.

To set the level:
```yaml title="future.router.yaml"
telemetry:
  instrumentation:
    events:
      router:
        acme.event:
          level: info # trace, debug, info, warn, error, off
          # ...
```

### `condition`

Custom events can be configured to emit under specific conditions, for example if the response status code is 200.

In `router.yaml`, set a `condition` with an equality (`eq`) check:

```yaml title="future.router.yaml"
telemetry:
  instrumentation:
    events:
      router:
        acme.event:
          # ...
          condition:
            eq:
              - 200
              - response_status: Code
```

For more details, see [Conditions](/router/configuration/telemetry/instrumentation/conditions).

### `attributes`

Custom events may have attributes attached to them from the router's request lifecycle. These attributes are used to filter and group spans in your APM.

Attributes may be drawn from [standard attributes](/router/configuration/telemetry/instrumentation/standard-attributes) or [selectors](/router/configuration/telemetry/instrumentation/selectors).
The attributes available depend on the service of the request lifecycle.

```yaml title="future.router.yaml"
telemetry:
  instrumentation:
    events:
      router:
        my.event:
          # ...
          attributes:
            # Standard attributes
            http.response.status_code: true
            # Custom attributes
            "my_attribute":
              response_header: "x-my-header"
```

## Event configuration reference

You can configure events with the following options:

| Option             | Values                                                                       | Default | Description                                                 |
|--------------------|------------------------------------------------------------------------------|---------|-------------------------------------------------------------|
| `<attribute-name>` |                                                                              |         | The name of the custom attribute.                           |
| `attributes`       | [standard attributes](/router/configuration/telemetry/instrumentation/standard-attributes) or [selectors](/router/configuration/telemetry/instrumentation/selectors)     |         | The attributes of the custom log event.                     |
| `condition`        | [conditions](/router/configuration/telemetry/instrumentation/conditions)                                                   |         | The condition that must be met for the event to be emitted. |
| `error`            | `trace`\|`info`\|`warn`\|`error`\| `off`                                     | `off`   | The level of the error log event.                           |
| `level`            | `trace`\|`info`\|`warn`\|`error`\| `off`                                     | `off`   | The level of the custom log event.                          |
| `message`          |                                                                              |         | The message of the custom log event.                        |
| `on`               | `request`\|`response`\|`error`                                               |         | When to trigger the event.                                  |
| `request`          | `trace`\|`info`\|`warn`\|`error`\| `off`                                     | `off`   | The level of the request log event.                         |
| `response`         | `trace`\|`info`\|`warn`\|`error`\| `off`                                     | `off`   | The level of the response log event.                        |

## Event configuration examples

### Standard and custom events

You can use both standard events and custom events in the same configuration. The example below has all the standard events (`request`, `response`, `error`) and one custom event (`my.event`) with a condition:

```yaml title="future.router.yaml"
telemetry:
  instrumentation:
    events:
      router:
        # Standard events
        request: info
        response: info
        error: info
  
        # Custom events
        my.event:
          message: "my event message"
          level: info
          on: request
          attributes:
            http.response.body.size: false
          # Only log when the x-log-request header is `log` 
          condition:
            eq:
              - "log"
              - request_header: "x-log-request"
          
      supergraph:
          # Custom event configuration for supergraph service ...
      subgraph:
          # Custom event configuration for subgraph service ...
      connector:
          # Custom event configuration for HTTP connectors ...
```

### Debugging subscriptions

When developing and debugging the router, you might want to log all subscription events. The example configuration below logs all subscription events for both errors and data.

<Note>

Logs of all subscription errors and data may contain personally identifiable information (PII), so make sure not to log PII in your production environments and only enable it for development.

</Note>


```yaml title="router.yaml"
telemetry:
  instrumentation:
    events:
      supergraph:
        subscription.event:
          message: subscription event
          on: event_response # on every subscription event
          level: info
          # Only display event if it's a subscription event
          condition:
            eq:
            - operation_kind: string
            - subscription
          attributes:
            response.data:
              response_data: $ # Display all the response data payload
            response.errors:
              response_errors: $ # Display all the response errors payload
```
